<?php

namespace App\Http\Controllers\App;

use App\Http\Controllers\Controller;
use App\Http\Requests\PlaceOrderRequest;
use App\Http\Resources\OrderResource;
use App\Models\Cart;
use App\Models\Merchant;
use App\Models\Order;
use App\Models\OrderAddress;
use App\Models\OrderProduct;
use App\Models\PayInfo;
use App\Models\Product;
use App\Models\SUsers;
use App\Rules\NumericRule;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Validator;
use Yansongda\Pay\Pay;

class OrderController extends Controller
{

    /**
     * @param PlaceOrderRequest $request
     * @return array
     * @throws \Throwable
     */
    public function placeOrder(PlaceOrderRequest $request){
        $config = config('wx.payconfig');
        $user = getUser($request);
        $products = $request->get('products');
        $address = $request->get('address');

        $order_type = 1;
        $quantity = 0;
        $postage = 0;
        $order_amount = 0.00;
        $payment = 0.00;
        $goods = [];
        $merchants = [];
        $share = false;
        $merchantAmount = [] ;
        for ($i=0 ;$i<count($products);$i++){
            $product = Product::findOrFail($products[$i]['id']);
            $product['activity_id'] = null;
            //判断当前商品是内外销，内销不能往外销售
            if ($product['domestic'] == 1){
                $share = true;
                $merchant = Merchant::findOrFail($product['merchant_id']);
                if ($merchant['province'] !== $address['province'] || $merchant['city'] !== $address['city']
                    || $merchant['district'] !== $address['district'] || !strstr($address['detail'],$merchant['town'])){
                    return [
                        'result'=>"failed",
                        'message'=>"当前地址不在商品的配送范围",
                    ];
                }
            }
            //判断商品是否已下架
            if ($product['shelves'] == 0){
                return [
                    'result'=>"failed",
                    'message'=>"该订单呢存在已下架商品，请刷新页面重新下单！",
                ];
            }


            //判断商品库存是否足够


            $order_amount += $product['price']*$products[$i]['count'];
            $product['quantity'] = $products[$i]['count'];

            $flag = true;
            foreach ($merchants as $merchant) {
                if ($merchant == $product['merchant_id']) {
                    $goods[$merchant][] = $product;
                    $merchantAmount[$merchant] += $product['price']*$products[$i]['count'];
                    $flag = false;
                    break;
                }
            }
            if ($flag) {
                $merchants[] = $product['merchant_id'];
                $goods[$product['merchant_id']] = [$product];
                $merchantAmount[$product['merchant_id']] = $product['price']*$products[$i]['count'];
            }
        }
        //使用优惠券
        $payment = $order_amount;

        $toUser = SUsers::where('openid',$request->get('shareOpenId'))->first();
        $toUser_id = -1;
        if(!empty($toUser)){
            if ($toUser['id'] != $user->id && $toUser['has_share'] == 1 && $share){
                $toUser_id = $toUser['id'];
                Log::info('用户分享下单=========user_id:'.$user->id.'========to_user_id:'.$toUser_id);
            }
        }
        //下单
        DB::beginTransaction();
        try {
            $time = time();

            $order_address = new OrderAddress;
            $order_address['receiver_name'] = $address['username'];
            $order_address['receiver_phone'] = $address['phone'];
            $order_address['province'] = $address['province'];
            $order_address['city'] = $address['city'];
            $order_address['district'] = $address['district'];
            $order_address['detail'] = $address['detail'];
            foreach ($merchants as $merchant) {
                $order = new Order;
                $order['user_id'] = $user->id;
                $order['to_user_id'] = $toUser_id;
                $order['merchant_id'] = $merchant;
                $order['order_type'] = $order_type;
                $order['postage'] = 0;         // 运费根据商家定
                $order['order_amount'] = $merchantAmount[$merchant];
                $order['payment'] = $merchantAmount[$merchant];//优惠券使用时按比例叫掉对应商家的订单金额
                $order['trade_no'] = $time;
                $order->saveOrFail();
                $order_address['order_id'] = $order['id'];
                $order_address->saveOrFail();
                foreach ($goods[$merchant] as $good) {
                    $order_product = new OrderProduct;
                    $order_product['order_id'] = $order->id;
                    $order_product['product_id'] = $good->id;
                    $order_product['user_id'] = $user->id;
                    $order_product['product_name'] = $good->name;
                    $order_product['current_price'] = $good->price;
                    $order_product['activity_type'] = $good->activity_type;
                    $order_product['activity_id'] = $good->activity_id;
                    $order_product['quantity'] = $good->quantity;
                    $order_product['total_price'] = $good->price * $good->quantity;
                    $order_product->saveOrFail();
                    if ($request->get('is_cart')){
                        Cart::where('user_id',$user->id)->where('product_id',$good->id)->delete();
                    }
                }
            }



            DB::commit();
        }catch (\Exception $exception){
            DB::rollBack();
            return [
                'result'=>'failed',
                'message'=>$exception->getMessage()
            ];
        }

        // 机器人下的单不需要支付
        if ($request->get('no_pay') == 1) {
            return [
                'result'=>'success'
            ];
        }

        //发起支付
        $pay_order = [
            'out_trade_no' => $time,
            'total_fee' => $payment * 100, // **单位：分**
            'body' => $user['nickname'],
            'openid' => $user->openid,
        ];

        $pay = Pay::wechat($config)->miniapp($pay_order);
        $pay_info = new PayInfo;
        $pay_info['user_id'] = $user->id;
        $pay_info['pay_platform'] = 1;
        $pay_info['platform_status'] = 0;
        $pay_info['order_amount'] = $payment;
        $pay_info['sign_type'] = $pay['signType'];
        $pay_info['time_stamp'] = $pay['timeStamp'];
        $pay_info['package'] = $pay['package'];
        $pay_info['nonce_str'] = $pay['nonceStr'];
        $pay_info['pay_sign'] = $pay['paySign'];
        $pay_info['trade_no'] = $time;
        $pay_info->saveOrFail();



        return [
            'result'=>'success',
            'data'=>$pay
        ];

    }



    //支付验签
    public function notify(Request $request)
    {
        $config = config('wx.payconfig');
        Log::info('************************************* 支付结果通知 *************************************');
        $pay = Pay::wechat($config);

        try{
            $data = $pay->verify(); // 是的，验签就这么简单！
            $results = $data->all();
            Log::info('支付结果所有数据', $results);
            $tradeNo = $data->get('out_trade_no');
            $totalFee = $data->get('total_fee');
            $pay_info = PayInfo::where('trade_no', $tradeNo)->first();
            if ($pay_info['platform_status'] == 1){
                return $pay->success();
            }
            //判断订单金额与支付金额是否一致
            if ($totalFee != $pay_info['order_amount']*100){
                DB::beginTransaction();
                try {
                $pay_info['remark'] = '订单金额与支付金额不一致！';
                $pay_info['platform_status'] = 2;
                $pay_info['total_fee'] = $totalFee ;
                $pay_info['platform_number'] = $data->get('transaction_id');
                $pay_info->saveOrFail();
                Order::where('trade_no',$tradeNo)->update(['status'=>5]);
                DB::commit();
                return $pay->success();
                }catch (\Exception $exception){
                    Log::info('验签失败:', $exception);
                    DB::rollBack();
                }
            }



            DB::beginTransaction();
            try {
                Order::where('trade_no',$tradeNo)->update(['status'=>2,'pay_time'=>$data->get('time_end')]);

                Log::info('支付结果的订单编号为：' . $tradeNo);

                $pay_info['platform_status'] = 1;
                $pay_info['total_fee'] = $totalFee;
                $pay_info['platform_number'] = $data->get('transaction_id');
                $pay_info->saveOrFail();
                DB::commit();
                return $pay->success();
            }catch (\Exception $exception){
                DB::rollBack();
                Log::info('验签失败:', $exception);
                throw $exception;
            }
        } catch (\Exception $e) {
            Log::info($e->getMessage()) ;
        }

        return $pay->success();// laravel 框架中请直接 `return $pay->success()`
    }


    /**
     * 继续付款，超过15分钟自动取消
     * @param Request $request
     * @return array
     */
    public function rePlaceOrder(Request $request){
        $validator = Validator::make($request->all(), [
            'trade_no' => ['required','numeric'],
            'openid' => ['required'],
        ]);
        if ($validator->fails()) {
            return [
                "result" => "failed",
                "message" => $validator->errors()
            ];
        }
        $config = config('wx.payconfig');
        $user = getUser($request);
        $order = PayInfo::where('user_id',$user->id)
            ->where('trade_no',$request->get('trade_no'))
            ->first();
        if (empty($order)){
            Order::where('user_id',$user->id)->where('trade_no',$order['trade_no'])->delete();
            Log::info('====商户订单号出错，无此订单号，已自动删除,商户订单号（trade_no）为：'.$order['trade_no']);
            return [
                "result" => "failed",
                "message" => '该订单不存在，请联系管理员！'
            ];
        }
        if ($order['platform_status'] != 0){
            $message = '订单状态出错,请联系管理员';
            switch ($order['platform_status']){
                case 1:{$message='订单已支付，请刷新页面！';break;}
                case 2:{$message='订单已取消，无法进行支付！';break;}
                default:break;
            }
            Log::info('====pay_info表数据出错，商户订单号为：'.$order['trade_no']);
            return [
                "result" => "failed",
                "message" => $message
            ];
        }
        $carbon = Carbon::parse ($order['created_at']); // 格式化一个时间日期字符串为 carbon 对象
        $int = Carbon::now()->diffInMinutes($carbon, true); // $int 为绝对值

        if ($int > 15){
            //超过15分钟的订单取消
            DB::transaction(function ()use ($order,$user){
                $order['platform_status'] = 2;
                $order->saveOrFail();
                Order::where('user_id',$user->id)->where('trade_no',$order['trade_no'])->update(['status'=>5]);
            },5);
            Pay::wechat($config)->close($order['trade_no']);
            return[
                'result'=>'failed',
                'message'=>'订单已超时未支付，请重新下单！'
            ];
        }

        if ($order['platform_status'] ==0 && empty($order['total_fee'])){
            try{
                $pay = Pay::wechat($config)->find($request->get('trade_no'));
                if (strcmp($pay->get('trade_state'),'NOTPAY') == 0){
                    return [
                        'result'=>'success',
                        'data'=>[
                            'sign_type' => $order['sign_type'],
                            'nonce_str' => $order['nonce_str'],
                            'package' => $order['package'],
                            'pay_sign' => $order['pay_sign'],
                            'time_stamp' => $order['time_stamp'],
                        ]
                    ];
                }
            }catch (\Exception $exception){
                return [
                    'result' => 'failed',
                    'message'=>$exception->getMessage()
                ];
            }
        }else{
            return [
                'result' => 'failed',
                'message'=>"订单状态错误,请重新下单"
            ];
        }


    }



    /**
     * 订单列表
     * @param Request $request
     * @return array
     */
    public function getOrders(Request $request){
        $validator = Validator::make($request->all(), [
            'status_code' => ['required',new NumericRule],
            'openid' => ['required'],
        ]);
        if ($validator->fails()) {
            return [
                "result" => "failed",
                "message" => $validator->errors()
            ];
        }
        $user = getUser($request);
        $ready_pay = null;
        if ($request->get('status_code') == 0 || $request->get('status_code') == 1){
            $ready_pay = Order::where('user_id',$user->id)
                ->where('status',1)
                ->select('id','postage','status','trade_no','pay_time','created_at','updated_at', DB::raw('SUM(payment) as payment'),'tracking_type','tracking_number')
                ->groupBy('trade_no');
        }



        $orders = Order::where('user_id',$user->id)
            ->select('id','postage','status','trade_no','pay_time','created_at','updated_at','payment','tracking_type','tracking_number')
            ->when($request->get('status_code'),function ($query)use($request){
                return $query->where('status',$request->get('status_code'));
            })
            ->when($request->get('status_code')==0 || $request->get('status_code') == 1,function ($query)use ($ready_pay){
                return $query->where('status','<>',1)->union($ready_pay);
            })
            ->orderBy('updated_at','desc')
            ->paginate(10);



        return [
            'result'=>'success',
            'data'=>[
                'data'=>OrderResource::collection($orders),
                'last_page'=>$orders->lastPage()
            ]
        ];
    }

    /**
     * 删除订单
     * @param Request $request
     * @return array|string[]
     */
    public function deleteOrder(Request $request){
        $validator = Validator::make($request->all(), [
            'order_id' => ['required','numeric'],
            'openid' => ['required'],
        ]);
        if ($validator->fails()) {
            return [
                "result" => "failed",
                "message" => $validator->errors()
            ];
        }
        $order = Order::where('id',$request->get('order_id'))->first();
        if ($order){
            $order->delete();
        }else{
            return [
                'result'=>'failed',
                'message'=>'订单不存在或已被删除'
            ];
        }
        return [
            'result'=>'success',
            'message'=>'订单删除成功'
        ];
    }

    /**
     * 统计各种状态订单数量
     * @param Request $request
     * @return array
     */
    public function getOrderAmount(Request $request){
        $validator = Validator::make($request->all(), [
            'openid' => ['required'],
        ]);
        if ($validator->fails()) {
            return [
                "result" => "failed",
                "message" => $validator->errors()
            ];
        }
        $user = getUser($request);
        $ready_pay = Order::where('user_id',$user->id)->where('status',1)->distinct('trade_no')->count();
        $ready_send = Order::where('user_id',$user->id)->where('status',2)->count();
        $ready_get = Order::where('user_id',$user->id)->where('status',3)->count();

        return [
            'result' => 'success',
            'data'=>[
                'ready_pay' => $ready_pay,
                'ready_send' => $ready_send,
                'ready_get' => $ready_get,
            ]
        ];
    }



}
